{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import re\n",
    "from pyvis.network import Network\n",
    "from pyltp import Segmentor, Postagger, Parser, SementicRoleLabeller"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def parser_main(sentence):\n",
    "    LTP_DIR='./ltp_data_v3.4.0'\n",
    "    segmentor=Segmentor(os.path.join(LTP_DIR,'cws.model'))\n",
    "    postagger=Postagger(os.path.join(LTP_DIR,'pos.model'))\n",
    "    parser=Parser(os.path.join(LTP_DIR,'parser.model'))\n",
    "    labeller=SementicRoleLabeller(os.path.join(LTP_DIR,'pisrl_win.model'))\n",
    "    words=list(segmentor.segment(sentence))\n",
    "    postags=list(postagger.postag(words))\n",
    "    arcs=parser.parse(words,postags)\n",
    "    roles=labeller.label(words,postags,arcs)\n",
    "    roles_dict={key:{sub_key:[sub_key,*value] for sub_key,value in sub_data}for key,sub_data in roles}\n",
    "    return words,postags,arcs,roles_dict\n",
    "text='苏轼是宋朝的著名文学家，黄庭剪是苏轼的好朋友。苏轼擅长写词，而黄庭坚擅长写诗。黄庭坚游览黄州，并赞叹黄山之美。黄庭坚探望苏轼，并一起吟诗作对。'\n",
    "words, postags, arcs, roles_dict=parser_main(text)\n",
    "print('分词结果:',words)\n",
    "print('语义角色标注结果：',roles_dict)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def ruler(words, postags, roles_dict, role_index):\n",
    "    v=words[role_index]\n",
    "    role_info=roles_dict[role_index]\n",
    "    if 'A0' in role_info.keys() and 'A1' in role_info.keys():\n",
    "        s=''.join([words[word_index] for word_index in range(role_info['A0'][1], role_info['A0'][2]+1) if postags[word_index][0] not in ['w','u','x']and words[word_index]])\n",
    "        o=''.join([words[word_index] for word_index in range(role_info['A1'][1], role_info['A1'][2]+1) if postags[word_index][0] not in ['w','u','x']and words[word_index]])\n",
    "        if s and o:\n",
    "            return '1',[s,v,o]\n",
    "    return '4',[]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def triples_main(text):\n",
    "    sentences = [sentence for sentence in re.split(r'[? ？！!。；;：:\\n\\r]',text)if sentence]\n",
    "    svos=[]\n",
    "    for index,sentence in enumerate(sentences):\n",
    "        words, postages, arcs, roles_dict=parser_main(sentence)\n",
    "        for index in range(len(postages)):\n",
    "            if index in range(len(postags)):\n",
    "                if index in roles_dict:\n",
    "                    flag,triple=ruler(words,postags,roles_dict,index)\n",
    "                    if flag=='1':\n",
    "                        svos.append(triple)\n",
    "    return svos\n",
    "svos=triples_main(text)\n",
    "print('文本的三元组：svos={0}'.format(svos))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def create_node(net,subs1,subs2):\n",
    "    if len(subs1)!=0:\n",
    "        for i in range(len(subs1)):\n",
    "            net.add_node(i,label=subs1[i],color='blue')\n",
    "    if len(subs2)!=0:\n",
    "        for i in range(len(subs2)):\n",
    "            net.add_node(1000+i,label=subs2[i],color='green')\n",
    "def create_node_id_dic(net):\n",
    "    dic_node_id={}\n",
    "    for i in net.node_ids:\n",
    "        dic_node_id[str(net.node_map[i]['label'])]=i\n",
    "    return dic_node_id\n",
    "def create_network(net,kg_list,node_id_dic):\n",
    "    for m in range(len(kg_list)):\n",
    "        try:\n",
    "            net.add_edge(node_id_dic[kg_list[m][0]],node_id_dic[kg_list[m][2]],label=kg_list[m][1],color='red',width=2)\n",
    "        except AttributeError as e:\n",
    "            print(e,m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def find_similar_semantics(net,node_id_dic,target_node):\n",
    "    target_node_id=node_id_dic[target_node]\n",
    "    adjacent_nodes=net.neighbors(target_node_id)\n",
    "    similar_semantics=[node_id_dic_inverse[node_id] for node_id in adjacent_nodes]\n",
    "    return similar_semantics\n",
    "node_id_dic_inverse={v:k for k,v in dic_node_id.items()}\n",
    "similar=find_similar_semantics(net,dic_node_id, '苏轼')\n",
    "print('与目标词‘苏轼’语义相关的词：',similar)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
